package com.myproject.myblogserver.controller;

import com.myproject.myblogserver.contant.CommonConstants;
import com.myproject.myblogserver.dto.UserLoginDto;
import com.myproject.myblogserver.dto.UserRegisterDto;
import com.myproject.myblogserver.dto.user.UserInfoDisplayDto;
import com.myproject.myblogserver.dto.user.UserInfoUpdateDto;
import com.myproject.myblogserver.dto.user.UserLoginSuccessDto;
import com.myproject.myblogserver.entity.User;
import com.myproject.myblogserver.entity.UserFollow;
import com.myproject.myblogserver.service.IUserFollowService;
import com.myproject.myblogserver.service.IUserService;
import com.myproject.myblogserver.utils.JwtUtil;
import com.myproject.myblogserver.utils.TokenUtil;

import java.util.HashMap;
import java.util.Map;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author jiangweike
 * @since 2024-12-22
 */
@Controller
@RequestMapping("/user")
public class UserController {

    @Autowired
    private IUserService userService;

    @Autowired
    private IUserFollowService userFollowService;

    @PostMapping("/register")
    public ResponseEntity<?> register(@RequestBody UserRegisterDto userRegisterDto) {
        User registeredUser = userService.register(userRegisterDto);
        if (registeredUser != null) {
            return ResponseEntity.status(HttpStatus.CREATED).body("注册成功！");
        } else {
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("注册失败！");
        }
    }

    @PostMapping("/login")
    public ResponseEntity<?> login(@RequestBody UserLoginDto userLoginDto) {
        var user = userService.login(userLoginDto);
        if (user != null) {
            // 生成新的 Access Token 和 Refresh Token
            String newAccessToken = JwtUtil.generateAccessToken(user.getId().toString());
            String newRefreshToken = JwtUtil.generateRefreshToken(user.getId().toString());

            // 返回新的 Token
            Map<String, String> tokens = new HashMap<>();
            tokens.put("accessToken", newAccessToken);
            tokens.put("refreshToken", newRefreshToken);
            tokens.put("expiresIn", String.valueOf(JwtUtil.ACCESS_TOKEN_EXPIRATION_TIME / 1000)); // 单位：秒
            
            var userLoginSuccessDto =  new UserLoginSuccessDto();
            userLoginSuccessDto.setId(user.getId());
            userLoginSuccessDto.setName(user.getName());
            userLoginSuccessDto.setBio(user.getBio());
            userLoginSuccessDto.setAvatar(user.getAvatar());
            userLoginSuccessDto.setTokens(tokens);
            return ResponseEntity.ok(userLoginSuccessDto);
        } else {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("登录失败！");
        }
    }

    @GetMapping("/getUserInfo/{userId}")
    public ResponseEntity<?> get(@PathVariable Long userId,
            @RequestHeader("Authorization") String authHeader) {
        try {
            var userData = userService.lambdaQuery().eq(User::getId, userId)
                    .eq(User::getIsDeleted, CommonConstants.DELETED_STATUS_NO).select(
                            User::getName, User::getAvatar,
                            User::getEmail,
                            User::getBio,
                            User::getBirthdate,
                            User::getCreatedAt)
                    .one();

            var followingCount = userFollowService.lambdaQuery()
                    .eq(UserFollow::getIsDeleted, CommonConstants.DELETED_STATUS_NO)
                    .eq(UserFollow::getFollowerId, userId).count();
            var followerCount = userFollowService.lambdaQuery()
                    .eq(UserFollow::getIsDeleted, CommonConstants.DELETED_STATUS_NO)
                    .eq(UserFollow::getFollowingId, userId).count();

            var userInfoDisplayDto = new UserInfoDisplayDto();
            BeanUtils.copyProperties(userData, userInfoDisplayDto);
            userInfoDisplayDto.setFollowingCount(followingCount);
            userInfoDisplayDto.setFollowerCount(followerCount);
            return ResponseEntity.ok(userInfoDisplayDto);
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.NOT_FOUND).body("查询失败！");
        }
    }

    @PutMapping("/update")
    public ResponseEntity<?> updateUserInfo(@RequestBody UserInfoUpdateDto userInfoUpdateDto,
            @RequestHeader("Authorization") String authHeader) {
        try {
            // 从Refresh Token中提取用户ID
            String refreshToken = TokenUtil.extractToken(authHeader);
            String userId = JwtUtil.getUserIdFromToken(refreshToken);

            var user = userService.lambdaQuery().eq(User::getIsDeleted, CommonConstants.DELETED_STATUS_NO)
                    .eq(User::getId, Long.parseLong(userId)).one();
            BeanUtils.copyProperties(userInfoUpdateDto, user);
            userService.updateById(user);
            return ResponseEntity.ok("更新成功！");
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST)
                    .body("更新失败！");
        }
    }

    /**
     * 刷新 Token 接口
     */
    @PostMapping("/refresh-token")
    public ResponseEntity<?> refreshToken(@RequestHeader("Authorization") String authHeader) {
        try {
            var refreshToken = TokenUtil.extractToken(authHeader);
            // 验证 Refresh Token 是否有效
            if (!JwtUtil.validateToken(refreshToken)) {
                return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Refresh token expired or invalid");
            }

            // 从 Refresh Token 中获取用户Id
            String userId = JwtUtil.getUserIdFromToken(refreshToken);

            // 生成新的 Access Token 和 Refresh Token
            String newAccessToken = JwtUtil.generateAccessToken(userId);
            String newRefreshToken = JwtUtil.generateRefreshToken(userId);

            // 返回新的 Token
            Map<String, String> tokens = new HashMap<>();
            tokens.put("accessToken", newAccessToken);
            tokens.put("refreshToken", newRefreshToken);
            tokens.put("expiresIn", String.valueOf(JwtUtil.ACCESS_TOKEN_EXPIRATION_TIME / 1000)); // 单位：秒

            return ResponseEntity.ok(tokens);
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Invalid refresh token");
        }
    }
}
